/* OpenSSL headers */
#include <stdio.h>
#include "openssl/bio.h"
#include "openssl/ssl.h"
#include "openssl/err.h"

// 一个使用SSL BIO的客户端的例子
// 流程:
// <1> 建立一个SSL_CTX - ctx = SSL_CTX_new(SSLv23_method())
// <2> 设置client端的SSL BIO
// <3> 设置要连接的主机地址: BIO_set_conn_hostname
// <4> BIO_do_connect(ssl_bio) 
// <5> 使用BIO_write和BIO_read来发送和接收数据
int main(int argc, char **argv) {
  SSL_CTX *ctx;
  SSL *ssl;
  BIO *ssl_bio;

  char *wbuf = "this is a c -> s msg";
  char rbuf[128];
  memset(rbuf, 0, 128);

  /* Initializing OpenSSL */
  SSL_load_error_strings();
  ERR_load_BIO_strings();
  ERR_load_SSL_strings();
  OpenSSL_add_ssl_algorithms();

  ctx = SSL_CTX_new(SSLv23_method());
  if(ctx == NULL) {
    printf("SSL_CTX_new(SSLv23_method()) error\n");
    return -1;
  }

  ssl = SSL_new(ctx);
  ssl_bio = BIO_new_ssl_connect(ctx);
  if(ssl_bio == NULL)
  {
    printf("BIO_new_ssl_connect error\n");
    SSL_CTX_free(ctx);
    return -1;
  }


  BIO_set_conn_hostname(ssl_bio, "localhost:4422");
  if(BIO_do_connect(ssl_bio) <= 0)
  {
    printf("BIO_do_connect error\n");
    BIO_free_all(ssl_bio);
    SSL_CTX_free(ctx);
    return -1;
  }

  if(BIO_write(ssl_bio, wbuf, strlen(wbuf)) <= 0)
  {
    printf("SSL_write error\n");
    BIO_free_all(ssl_bio);
    SSL_CTX_free(ctx);
    return -1;
  }

  if(BIO_read(ssl_bio, rbuf, 128) <= 0) {
    printf("SSL_read error\n");
    BIO_free_all(ssl_bio);
    SSL_CTX_free(ctx);
    return -1;
  }

  printf("client# %s\n", rbuf);

  BIO_free_all(ssl_bio);
  SSL_CTX_free(ctx);
  return 0;
}
